package  
{
	
	
	import Components.Explosion;
	import Components.StaticBlock;
	import flash.geom.Vector3D;
	import flash.sampler.NewObjectSample;
	
	import nl.jorisdormans.phantom2D.ai.statemachines.StateMachine;
	import nl.jorisdormans.phantom2D.objects.GameObject;
	import nl.jorisdormans.phantom2D.particles.ParticleLayer;
	import nl.jorisdormans.phantom2D.core.Screen;
	import nl.jorisdormans.phantom2D.layers.Background;
	import nl.jorisdormans.phantom2D.objects.ObjectLayer;
	import nl.jorisdormans.phantom2D.objects.TiledObjectLayer;
	import nl.jorisdormans.phantom2D.cameras.CameraEase;
	import nl.jorisdormans.phantom2D.cameras.CameraWrapAround;
	import nl.jorisdormans.phantom2D.cameras.FollowObject;
	import nl.jorisdormans.phantom2D.cameras.RestrictToLayer;
	import nl.jorisdormans.phantom2D.thirdparty.sfxr.SfxrSynth;
	
	import Controllers.PowerupController;
	
	import generator.PlatformGenerator;
	import generator.Generator;
	
	import States.IdleState;
	
	import Components.Sounds;
	import Components.Health;
	import Components.ScoreDisplay;
	import Components.Block;
	import Components.SlopeLeft;
	import Components.SlopeRight;
	import Components.ChopperForm;
	
	import Powerups.FastPowerup;
	import Powerups.GravityHigh;
	import Powerups.GravityLow;
	import Powerups.SlowPowerup;
	
	/**
	 * ...
	 * @author Sebastiaan
	 */
	
	public class ChopperGame extends Screen
	{
		public var tol:TiledObjectLayer;												//The tiled object layer
		private var generator : generator.PlatformGenerator;							//The generator used for random level generator
		private var blockCount : int = 0;												//Used to not let multiple blocks spawn
		private var timer : Number = 2.5;
		public var block : Block;														//block  of the random placed wall
		public var block1 : Block;														//block 1 of the random placed wall
		public var block2 : Block;														//block 2 of the random placed wall
		public var block3 : Block;														//block 3 of the random placed wall
		public var block4 : Block;														//block 4 of the random placed wall
		public var block5 : Block;														//block 5 of the random placed wall
		public var block6 : Block;
		public var block7 : Block;
		public var Explode : Explosion;
		
		public static var boom : Boolean = false;
		public static var player : Player;	
		public static var form : ChopperForm;
		public static var playing : Boolean = true;
		
		public static var powerupChoose : int;											//is a number on which powerup to spawn
		
		public function ChopperGame(width : Number, height : Number) 
		{
			super(width, height);
			Sounds.init();																//initializes the sounds
				
			addComponent(new Background(0xA0A7FC, 0x2737F8, 0x05119E, 60));				//Sets the background and the color of the background
			addComponent(new ParticleLayer(1600, 600));									//Adds a particle layer to the screen so particles are visible
			addComponent(tol = new TiledObjectLayer(40, 30, 15, 4));					//Sets the tile size
			addComponent(new ScoreDisplay());											//Adds the scores to the screen
			addComponent(new PowerupController());										//Adds the powerupcontroller to the game
			addComponent(new StateMachine(new IdleState()));							//Sets the idlestate in motion
			player = new Player();														//Adds the player to the screen
			form = new ChopperForm();
			tol.addGameObject(form, new Vector3D(16, 200));
			tol.addGameObject(player, new Vector3D(16, 200));							
			
			//creates the top layer of the game screen
			tol.createObjects([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
							   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
							   2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3], [null,StaticBlock, SlopeRight, SlopeLeft]);
			
			generateLevel();															//generates the bottom halve of the screen
			
			camera.addComponent(new FollowObject(player));								//ensures the camera follows the player
			camera.addComponent(new CameraWrapAround(tol, true, false));				//Wraps the layer around the screen for infinite level
			camera.addComponent(new RestrictToLayer(tol, false, true));
			
		}
		
		override public function update(elapsedTime:Number):void 
		{
			super.update(elapsedTime);	
			form.position = player.position;
			spawnPowerup();																
			spawnBlock();
			loop();
			if (player.position.x > 1190 && blockCount == 1)							//Destroys blocks at the end of the screenlayer
			{
				block.destroyed = true;
				block1.destroyed = true;
				block2.destroyed = true;
				block3.destroyed = true;
				block4.destroyed = true;
				block5.destroyed = true;
				block6.destroyed = true;
				block7.destroyed = true;
				blockCount = 0;
			}
			
			if (boom)
			{
				Explode= new Explosion();
				tol.addGameObjectSorted(Explode, new Vector3D(player.position.x, player.position.y));
				boom = false;
			}
		}
		
		//Generates the bottom halve of the level
		private function generateLevel() : void
		{
			trace("Generating level...");
			var gen:PlatformGenerator = new PlatformGenerator();
			tol.addComponent(gen);
			tol.wrapTileConnections(true, false);
			
			gen.clearTiles(0);
			
			gen.generateRandomTiles(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1);
			
			for (var i: int; i < 9; i++)
				gen.iterate();
	
			gen.createCorners();
			gen.convertCellsToObjects();
		}
		
		//Generates a random number for the powerups
		private function randomSpawn() : int
		{
			var random : int = Math.ceil(Math.random() * 380) + 150;
			return random;
		}
		
		//Generates a random number for the blocks
		private function randomBlockSpawn() : int
		{
			var random : int = Math.ceil(Math.random() * 300) + 150;
			return random;
		}
		
		private function loop (): void
		{
			if (playing)
			{
				if(timer >= 2.5)
				{
					Sounds.chopperSound.play();
				}
				timer -= 0.1;
			
				if (timer < 0)
				{
					timer = 2.5;
				}
			}
		}
		
		//Spawns the blocks in the form of a wall
		private function spawnBlock() : void
		{
			if (blockCount == 0)
			{
				block = new Block();
				block1 = new Block();
				block2 = new Block();
				block3 = new Block();
				block4 = new Block();
				block5 = new Block();
				block6 = new Block();
				block7 = new Block();
				
				var random : int = randomBlockSpawn();
				tol.addGameObjectSorted(block, new Vector3D(camera.left - 25, random));
				tol.addGameObjectSorted(block1, new Vector3D(camera.left - 25, random + 25));
				tol.addGameObjectSorted(block2, new Vector3D(camera.left - 25, random - 25));
				tol.addGameObjectSorted(block3, new Vector3D(camera.left - 25, random - 50));
				tol.addGameObjectSorted(block4, new Vector3D(camera.left - 25, random + 50));
				tol.addGameObjectSorted(block5, new Vector3D(camera.left - 25, random + 75));
				tol.addGameObjectSorted(block6, new Vector3D(camera.left - 25, random - 75));
				tol.addGameObjectSorted(block7, new Vector3D(camera.left - 25, random + 100));
				trace("Spawned 4 Blocks");
				blockCount = 1;
			}
		}
		
		//Returns the player position
		public static function getPosition() : Vector3D
		{
			return player.position;
		}
		
		//Spawns the powerups at a random place
		public function spawnPowerup() : void
		{
			switch(powerupChoose)
			{
				case 1:	var fast : FastPowerup = new FastPowerup();
						tol.addGameObjectSorted(fast, new Vector3D(camera.left - 25, randomSpawn()));
						trace("Spawned fast powerup");
						powerupChoose = 0;
						break;
				
				case 2:	var slow : SlowPowerup = new SlowPowerup();
						tol.addGameObjectSorted(slow, new Vector3D(camera.left - 25, randomSpawn()));
						trace("Spawned slow powerup");
						powerupChoose = 0;
						break;
						
				case 3:	var hGrav : GravityHigh = new GravityHigh();
						tol.addGameObjectSorted(hGrav, new Vector3D(camera.left - 25, randomSpawn()));
						trace("Spawned hGrav powerup");
						powerupChoose = 0;
						break;
						
				case 4:	var lGrav : GravityLow = new GravityLow();
						tol.addGameObjectSorted(lGrav, new Vector3D(camera.left - 25, randomSpawn()));
						trace("Spawned lGrav powerup");
						powerupChoose = 0;
						break;
			}
		}
	}

}